#include<bits/stdc++.h>
using namespace std;

const int N=102;
int colors[N][N];
int n,m;
const int dr[4]={-1,0,1,0};
const int dc[4]={0,1,0,-1};
vector<int> edges[N][N];


int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&colors[i][j]);
        }
    }
    int sum[N][N];memset(sum,0,sizeof(sum));
    int in[N][N];memset(in,0,sizeof(in));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                int r1=i+dr[k],c1=j+dc[k];
                if(r1>=1&&r1<=n&&
                c1>=1&&c1<=m&&colors[r1][c1]>colors[i][j])
                {
                    edges[i][j].emplace_back(r1);
                    edges[i][j].emplace_back(c1);
                    in[r1][c1]++;
                }
            }
        }
    }
    //
    queue<int> que;
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    		if(in[i][j]==0){
    			que.push(i);
    			que.push(j);
			}
		}
	}
	int level;
	for(level=0;!que.empty();level++){
		int size=que.size()/2;
		for(int i=0;i<size;i++){
			int r=que.front();que.pop();
			int c=que.front();que.pop();
			for(int k=0;k<edges[r][c].size();k+=2){
				int r1=edges[r][c][k],c1=edges[r][c][k+1];
				in[r1][c1]--;
				if(in[r1][c1]==0){
					que.push(r1);
					que.push(c1);
				}
			}
		}
	}
	printf("%d",level);
	return 0;
}

